package com.farben.web.controller.utils.excel;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.farben.common.utils.file.FileUtils;
import com.google.common.collect.Lists;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.List;

public class ExcelUtils {
    private static final Logger log = LoggerFactory.getLogger(ExcelUtils.class);

    private static ExcelWriter excelWriter = null;
    private static WriteSheet writeSheet = null;
    private static File tempFile = null;
    private static boolean emptyFlag = true;

    /**
    * write data to response outputStream, can't append nextTime
    */
    public static void writeDataExcel(OutputStream os, Collection<?> data){
    EasyExcel.write(os)
        .sheet()
        .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
        .doWrite(Lists.newArrayList(data));
    }

    /**
     * write data to excel,can append nextTime
     * can define other sheet,write by one excelWriter
     */
    public static int appendDataToExcel(List<?> dataList, String sheetName){
        try{
            log.info("ExcelUtils dataList size:{}",dataList.size());
            writeSheet = EasyExcelFactory.writerSheet(sheetName).build();
            excelWriter.write(dataList,writeSheet);
        }catch (Exception e){
            log.warn("ExcelUtils appendDataToExcel:{}",e.getMessage());
        }
        if (dataList.size()>0){
            emptyFlag =false;
        }
        return dataList.size();
    }

    /**
     * 读取excel
     */
    public static List<?> readData(MultipartFile multipartFile,Class<?> head){
        List<?> result = Lists.newArrayList();
        try(InputStream is = multipartFile.getInputStream()){
            result = EasyExcel.read(is,head,null).sheet().doReadSync();
        }catch (IOException e){
            log.warn("ExcelUtils read excel error message:{}",e.getMessage());
        }
        return result;
    }

    @SuppressWarnings("unchecked")
    public static <T>  void initExcelFactory(String realPath,T head){
        log.info("ExcelUtils realPath:{}",realPath);
        if (excelWriter==null&&writeSheet==null){
            tempFile = new File(realPath);
            log.info("ExcelUtils tempFile:{}",tempFile);
            if (head instanceof Class){
                excelWriter = EasyExcelFactory.write(tempFile.getAbsolutePath())
                        .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                        .head((Class<?>) head).build();
            }
            if (head instanceof List){
                excelWriter = EasyExcelFactory.write(tempFile.getAbsolutePath())
                        .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                        .head((List<List<String>>) head).build();
            }
        }
    }

    @SneakyThrows
    public static byte[] getExcelBinaryData(){
        excelWriter.finish();
        if (emptyFlag){
            return new byte[]{};
        }
        byte[] bytes = tempFile.exists()? FileUtils.readFileToByteArray(tempFile):new byte[]{};
        log.info("ExcelUtils bytes:{}",bytes);
        return bytes;
    }

    @SneakyThrows
    public static void finish(){
        if (excelWriter!=null){
            excelWriter.finish();
            excelWriter = null;
            writeSheet = null;
        }
        if (tempFile.exists()){
            FileUtils.forceDelete(tempFile);
        }
    }

}
